package com.docmgmt.mvp.service;

import com.docmgmt.mvp.dto.LoginRequest;
import com.docmgmt.mvp.dto.LoginResponse;
import com.docmgmt.mvp.dto.RegisterRequest;
import com.docmgmt.mvp.entity.UserEntity;
import com.docmgmt.mvp.exception.BusinessException;
import com.docmgmt.mvp.exception.UnauthorizedException;
import com.docmgmt.mvp.mapper.UserMapper;
import com.docmgmt.mvp.util.JwtTokenProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
@RequiredArgsConstructor
public class AuthService {

    private final UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtTokenProvider jwtTokenProvider;

    @Value("${jwt.expiration}")
    private Long jwtExpiration;

    @Transactional
    public LoginResponse register(RegisterRequest request) {
        log.info("User registration attempt: username={}", request.getUsername());

        if (userMapper.selectByUsername(request.getUsername()) != null) {
            throw new BusinessException("Username already exists");
        }

        if (userMapper.selectByEmail(request.getEmail()) != null) {
            throw new BusinessException("Email already exists");
        }

        UserEntity user = new UserEntity();
        user.setUsername(request.getUsername());
        user.setPasswordHash(passwordEncoder.encode(request.getPassword()));
        user.setEmail(request.getEmail());
        user.setFullName(request.getFullName());
        user.setDepartmentId(request.getDepartmentId());
        user.setStatus("active");
        user.setStorageQuota(10737418240L);
        user.setStorageUsed(0L);

        userMapper.insert(user);
        log.info("User registered successfully: userId={}", user.getId());

        String token = jwtTokenProvider.generateToken(user.getId(), user.getUsername());

        return LoginResponse.builder()
                .token(token)
                .tokenType("Bearer")
                .expiresIn(jwtExpiration)
                .userId(user.getId())
                .username(user.getUsername())
                .fullName(user.getFullName())
                .build();
    }

    public LoginResponse login(LoginRequest request) {
        log.info("User login attempt: username={}", request.getUsername());

        UserEntity user = userMapper.selectByUsername(request.getUsername());
        if (user == null) {
            throw new UnauthorizedException("Invalid username or password");
        }

        if (!passwordEncoder.matches(request.getPassword(), user.getPasswordHash())) {
            throw new UnauthorizedException("Invalid username or password");
        }

        if ("inactive".equals(user.getStatus()) || "locked".equals(user.getStatus())) {
            throw new BusinessException("Account is " + user.getStatus());
        }

        String token = jwtTokenProvider.generateToken(user.getId(), user.getUsername());
        log.info("User logged in successfully: userId={}", user.getId());

        return LoginResponse.builder()
                .token(token)
                .tokenType("Bearer")
                .expiresIn(jwtExpiration)
                .userId(user.getId())
                .username(user.getUsername())
                .fullName(user.getFullName())
                .build();
    }
}
